package com.weijin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.weijin.exception.AppException;
import com.weijin.mapper.VacationMapper;
import com.weijin.model.entities.User;
import com.weijin.model.entities.Vacation;
import com.weijin.model.enums.ExceptionCode;
import com.weijin.model.enums.UserRole;
import com.weijin.model.from.OperateFrom;
import com.weijin.model.from.VacationFrom;
import com.weijin.service.IUserService;
import com.weijin.service.IVacationService;
import com.weijin.utils.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @Author WeiJin
 * @Version 1.0
 * @Date 2025/3/28 19:37
 */
@Service
public class VacationServiceImpl implements IVacationService {

    @Autowired
    private VacationMapper vacationMapper;
    @Autowired
    private IUserService userService;

    @Override
    public Vacation submitVacation(VacationFrom vacationFrom) {
        // 请求参数校验
        if (Objects.isNull(vacationFrom)) {
            throw new AppException(ExceptionCode.REQUEST_PARAMETER_IS_NULL);
        }

        if (vacationFrom.getType() < 1 || vacationFrom.getType() > 4){
            throw new AppException(ExceptionCode.VACATION_TYPE_ERROR);
        }

        // 验证用户是否存在
        User user = userService.queryUserById(vacationFrom.getUserId());
        if (Objects.isNull(user)) {
            throw new AppException(ExceptionCode.USER_IS_NULL);
        }

        // 将字符串类型的时间日期转换为LocalDateTime类型
        LocalDate startDate = DateTimeUtil.strToDate(vacationFrom.getStartDate());
        LocalDate endDate = DateTimeUtil.strToDate(vacationFrom.getEndDate());

        // 开始时间或结束时间早于当前时间抛出异常
        if (startDate.isBefore(LocalDate.now()) || endDate.isBefore(LocalDate.now())) {
            throw new AppException(ExceptionCode.START_DATE_OR_END_DATE_EARLY_NOW);
        }

        // 如果结束日期早于开始日期 抛异常
        if (endDate.isBefore(startDate)) {
            throw new AppException(ExceptionCode.END_DATE_EARLY_START_DATE);
        }

        // 验证角色 BOSS不能请假，BOSS请假无人审批
        if (UserRole.BOSS.equals(user.getRole())) {
            throw new AppException(ExceptionCode.BOSS_NOT_ALLOW_SUBMIT_VACATION);
        }

        // 构建Vacation信息
        Vacation vacation = new Vacation(vacationFrom.getUserId(), vacationFrom.getType(),
                startDate, endDate, vacationFrom.getReason());
        // 保存到数据库
        int inserted = vacationMapper.insert(vacation);
        if (inserted > 0) {
            return vacation;
        }
        throw new AppException(ExceptionCode.ADD_FAILED);
    }

    @Override
    public List<Vacation> queryAll() {
        LambdaQueryWrapper<Vacation> wrapper = new LambdaQueryWrapper<>();
        List<Vacation> vacations = vacationMapper.selectList(wrapper);
        return vacations;
    }

    @Override
    public List<Vacation> queryLowerLevelUntreated(String userId) {
        // 验证用户是否存在
        User user = userService.queryUserById(userId);
        if (Objects.isNull(user)) {
            throw new AppException(ExceptionCode.USER_IS_NULL);
        }

        // 验证角色 员工不能使用该接口
        if (UserRole.STAFF.equals(user.getRole())) {
            throw new AppException(ExceptionCode.BOSS_NOT_ALLOW_SUBMIT_VACATION);
        }
        // 根据角色查询下一级别的请假信息
        return vacationMapper.selectLowerLevelUntreated(user.getRole().name());
    }

    @Override
    public int operateVacation(OperateFrom operateFrom) {
        // 请求参数校验
        if (Objects.isNull(operateFrom)) {
            throw new AppException(ExceptionCode.REQUEST_PARAMETER_IS_NULL);
        }

        // 验证审批人 用户是否存在
        User operateUser = userService.queryUserById(operateFrom.getOperatorId());
        if (Objects.isNull(operateUser)) {
            throw new AppException(ExceptionCode.USER_IS_NULL);
        }
        // 审批人角色为员工，抛无权限异常
        if (UserRole.STAFF.equals(operateUser.getRole())) {
            throw new AppException(ExceptionCode.NOT_AUTHORITY);
        }

        // 获取请假信息
        Vacation vacation = vacationMapper.selectById(operateFrom.getVacationId());
        // 校验请假信息
        if (Objects.isNull(vacation)) {
            throw new AppException(ExceptionCode.VACATION_NOT_EXIST);
        }
        // 获取请假人的用户信息
        User vacateUser = userService.queryUserById(vacation.getUserId());
        // 如果请假人是员工，审批人是老板，抛出无权限 不能越级审批
        if (UserRole.BOSS.equals(operateUser.getRole()) && UserRole.STAFF.equals(vacateUser.getRole())) {
            throw new AppException(ExceptionCode.USER_IS_NULL);
        }
        // 如果请假人是主管，审批人也是主管，抛出无权限 不能同级审批
        if (UserRole.SUPERVISOR.equals(operateUser.getRole()) && UserRole.SUPERVISOR.equals(vacateUser.getRole())) {
            throw new AppException(ExceptionCode.USER_IS_NULL);
        }
        // 补充请假
        vacation.setOperatorId(operateFrom.getOperatorId());
        vacation.setIsAgree(operateFrom.getIsAgree());
        vacation.setOperateTime(LocalDateTime.now());
        // 保存到数据库并返回影响数据库记录条数
        return vacationMapper.updateById(vacation);
    }

    @Override
    public Vacation queryVacationById(String id) {
        return vacationMapper.selectById(id);
    }
}
